// pkg/ublk/ioctl.go
// ublk ioctl 命令定义

package ublk

import (
	"syscall"
	"unsafe"
)

const (
	// ioctl 命令
	UBLK_CMD_GET_QUEUE_AFFINITY = 1
	UBLK_CMD_GET_DEV            = 2
	UBLK_CMD_ADD_DEV            = 0x10001
	UBLK_CMD_DEL_DEV            = 0x10002
	UBLK_CMD_START_DEV          = 0x10003
	UBLK_CMD_STOP_DEV           = 0x10004
	UBLK_CMD_SET_PARAMS         = 0x10005
	UBLK_CMD_GET_PARAMS         = 0x10006
)

// UblkDeviceInfo 设备信息结构
type UblkDeviceInfo struct {
	DevID      uint32
	QueueDepth uint16
	BlockSize  uint32
	DeviceSize uint64
	OpsFlags   uint32
}

// UblkIOEvent ublk I/O 事件
type UblkIOEvent struct {
	OpCode  uint8
	_       [7]byte // padding
	UserDat uint64
	Addr    uint64
	Len     uint32
	_       [4]byte // padding
}

// DoUblkIoctl 执行 ioctl 命令
func DoUblkIoctl(fd int, cmd uint, arg unsafe.Pointer) (int, error) {
	r, _, errno := syscall.RawSyscall(
		syscall.SYS_IOCTL,
		uintptr(fd),
		uintptr(cmd),
		uintptr(arg),
	)

	if errno != 0 {
		return int(r), syscall.Errno(errno)
	}

	return int(r), nil
}

// ---
